package cn.sylinx.hbatis.ext.common.repository;

import java.io.Serializable;
import java.util.List;

import cn.sylinx.hbatis.db.common.Callable;
import cn.sylinx.hbatis.db.common.FS;
import cn.sylinx.hbatis.db.common.ITransaction;
import cn.sylinx.hbatis.db.common.Page;
import cn.sylinx.hbatis.db.common.Record;
import cn.sylinx.hbatis.db.dialect.Dialect;
import cn.sylinx.hbatis.db.mapper.QueryMapper;
import cn.sylinx.hbatis.ext.model.GenericModel;
import cn.sylinx.hbatis.kit.Pair;
import cn.sylinx.hbatis.kit.Ret;

public interface CommonDaoService extends FluentSqlSupport {

	/**
	 * 获取数据源名称
	 * 
	 * @return
	 */
	public String getDatasourceName();

	/**
	 * 获取数据库类型
	 * 
	 * @return
	 */
	public Dialect getDialect();

	/**
	 * 自定义操作
	 * 
	 * @param callable
	 * @return
	 */
	public <T> T call(Callable<T> callable);

	/**
	 * 创建fluent sql
	 * 
	 * @param clazz
	 * @return
	 */
	public <T> FS<T> createFS(Class<T> clazz);

	/**
	 * 查询
	 * 
	 * @param sql
	 * @param mapper
	 * @param params
	 * @return
	 */
	public <T> List<T> query(final String sql, final QueryMapper<T> mapper, final Object... params);

	/**
	 * 单列
	 * 
	 * @param sql
	 * @param clazz
	 * @param params
	 * @return
	 */
	public <T> List<T> queryObject(final String sql, final Class<T> clazz, final Object... params);

	/**
	 * 缓存查询
	 * 
	 * @param sql
	 * @param clazz
	 * @param params
	 * @return
	 */
	public <T> List<T> queryObjectWithCache(final String sql, final Class<T> clazz, final Object... params);

	/**
	 * 单列，第一条记录
	 * 
	 * @param sql
	 * @param clazz
	 * @param params
	 * @return
	 */
	public <T> T queryFirstObject(final String sql, final Class<T> clazz, final Object... params);

	/**
	 * 缓存查询
	 * 
	 * @param sql
	 * @param clazz
	 * @param params
	 * @return
	 */
	public <T> T queryFirstObjectWithCache(final String sql, final Class<T> clazz, final Object... params);

	/**
	 * 查询记录
	 * 
	 * 
	 * @param nativeSql
	 * @param params
	 * @return
	 */
	List<Record> queryRecordsWithSql(String nativeSql, Object... params);

	/**
	 * 查询记录
	 * 
	 * 
	 * @param nativeSql
	 * @param params
	 * @return
	 */
	Record queryRecordWithSql(String nativeSql, Object... params);

	/**
	 * 更新
	 * 
	 * 
	 * @param nativeSql
	 * @param params
	 * @return
	 */
	int updateWithSql(String nativeSql, Object... params);

	/**
	 * 事务处理
	 * 
	 * @param transactions
	 * @return
	 */
	public boolean transaction(ITransaction transactions);

	/**
	 * 事务处理，带返回结果
	 * 
	 * @param transactions
	 * @return
	 */
	public Ret transactionWithReturn(ITransaction transactions);

	/**
	 * 执行脚本,包括ddl
	 * 
	 * @param resource
	 * @return
	 */
	boolean executeLargeUpdate(final List<String> nativeExeSqlList);

	boolean existTable(final String schema, final String table);

	boolean existTableColumn(final String schema, final String table, final String column);

	<T> int update(T t);

	<T> int updateObject(T t);

	<T> int delete(T t);

	<T> int deleteByPk(Object id, Class<T> clz);

	<T> int delete(List<Pair> kvList, Class<T> clz);

	<T> int deleteObjectByPk(Object pk, Class<T> clz);

	<T> int deleteObject(List<Pair> kvList, Class<T> clz);

	<T> T get(Object id, Class<T> clz);

	<T> T get(Object id, Class<T> clz, String[] fields);

	<T> T get(Object id, Class<T> clz, String[] fields, boolean cached);

	<T> T get(Object id, Class<T> clz, boolean cached);

	/**
	 * T对象中必须有id字段
	 */
	<T> T getObject(Object pk, Class<T> clz);

	<T> T getByNumber(String number, Class<T> clz);

	<T> T getByField(Pair kv, Class<T> clz);

	<T> List<T> getByField(List<Pair> kvList, Class<T> clz);

	<T> T getObjectByNumber(String number, Class<T> clz);

	<T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz);

	<T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz, String[] fields);

	/**
	 * 获取记录
	 * 
	 * @param pair
	 * @param clz
	 * @return
	 */
	<T> Record getRecordByField(Pair pair, Class<T> clz);

	<T> Record getRecordByField(List<Pair> kvList, Class<T> clz);

	<T> List<Record> getRecordsByField(List<Pair> kvList, Class<T> clz);

	<T> List<Record> getRecordsByField(List<Pair> kvList, Class<T> clz, String[] fields);

	/**
	 * 是否使用缓存查询
	 * 
	 * @param kvList
	 * @param clz
	 * @param cached
	 * @return
	 */
	<T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz, boolean cached);

	<T> List<T> getObjectByField(List<Pair> kvList, Class<T> clz, String[] fields, boolean cached);

	<T> List<Record> getRecordsByField(List<Pair> kvList, Class<T> clz, String[] fields, boolean cached);

	<T> T getObjectByField(Pair kv, Class<T> clz);

	<T extends GenericModel> T add(T t);

	<T> Ret addWithRet(T t);
	
	<T> boolean justAdd(T t);
	
	Object insert(String insertSql, Object... params);

	/**
	 * return pk
	 * 
	 * @param t
	 * @return
	 */
	<T> Serializable addObject(T t);

	/**
	 * 批量添加对象
	 * 
	 * @param t
	 * @return 主键列表
	 */
	<T> List<Object> batchAddObject(List<T> objectList);

	/**
	 * 批量添加对象
	 * 
	 * @param objectList
	 * @return 是否批量添加成功
	 */
	<T> boolean justBatchAddObject(List<T> objectList);

	<T> boolean justAddObject(T t);

	<T> List<T> query(Class<T> clz);

	<T> List<T> querySqlList(String sql, Class<T> clz, Object... params);
	
	<T> T querySqlFirst(String sql, Class<T> clz, Object... params);

	<T> Page<T> queryPage(Class<T> clz, int pageNumber, int pageSize);

	<T> Page<T> queryPage(Class<T> clz, int pageNumber);

	<T> Page<T> queryPage(String sql, int pageNumber, int pageSize, Class<T> clz, Object... params);

	<T> Page<Record> queryPageRecords(Class<T> clz, int pageNumber, int pageSize);

	<T> Page<Record> queryPageRecords(Class<T> clz, int pageNumber);

	<T> Page<Record> queryPageRecords(String sql, int pageNumber, int pageSize, Object... params);

	<T> List<T> queryWithCache(Class<T> clz);

	<T> List<T> querySqlListWithCache(String nativeSql, Class<T> clz, Object... params);

	<T> T querySqlFirstWithCache(String nativeSql, Class<T> clz, Object... params);

	List<Record> querySqlRecordsWithCache(String sql, Object... params);

	/**
	 * 批量执行语句
	 * 
	 * @param sql
	 *            sql语句（更新、插入、删除）
	 * @return 影响行数
	 */
	public int[] batch(final List<String> sql);

	/**
	 * 批量执行语句
	 * 
	 * @param sql
	 *            sql语句（更新、插入、删除）
	 * @param params
	 *            参数
	 * @return 影响行数
	 */
	public int[] batch(final String sql, final Object[][] params);

	/**
	 * 批量执行语句
	 * 
	 * @param sql
	 *            sql语句（更新、插入、删除）
	 * @param params
	 *            参数
	 * @param batchSize
	 *            批量提交量
	 * @return 影响行数
	 */
	public int[] batch(final String sql, final Object[][] params, final int batchSize);

	/**
	 * 批量执行语句
	 * 
	 * @param sqlList
	 *            sql列表
	 * @param batchSize
	 *            批量提交量
	 * @return 影响行数
	 */
	public int[] batch(final List<String> sqlList, final int batchSize);

}
